﻿#region Copyright (c) 2000-2013 Developer Express Inc.
/*
{*******************************************************************}
{                                                                   }
{       Developer Express .NET Component Library                    }
{                                                                   }
{                                                                   }
{       Copyright (c) 2000-2013 Developer Express Inc.              }
{       ALL RIGHTS RESERVED                                         }
{                                                                   }
{   The entire contents of this file is protected by U.S. and       }
{   International Copyright Laws. Unauthorized reproduction,        }
{   reverse-engineering, and distribution of all or any portion of  }
{   the code contained in this file is strictly prohibited and may  }
{   result in severe civil and criminal penalties and will be       }
{   prosecuted to the maximum extent possible under the law.        }
{                                                                   }
{   RESTRICTIONS                                                    }
{                                                                   }
{   THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES           }
{   ARE CONFIDENTIAL AND PROPRIETARY TRADE                          }
{   SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS   }
{   LICENSED TO DISTRIBUTE THE PRODUCT AND ALL ACCOMPANYING .NET    }
{   CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY.                 }
{                                                                   }
{   THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED      }
{   FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE        }
{   COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE       }
{   AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT  }
{   AND PERMISSION FROM DEVELOPER EXPRESS INC.                      }
{                                                                   }
{   CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON       }
{   ADDITIONAL RESTRICTIONS.                                        }
{                                                                   }
{*******************************************************************}
*/
#endregion Copyright (c) 2000-2013 Developer Express Inc.

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Markup;
using System.Windows.Media;
using UColor.Core.Helpers;
using DevExpress.Xpf.Core;
using DevExpress.Xpf.Core.Native;
using UColor.WPF.Helpers;
#if !DEMO
using DevExpress.Utils;
#endif
#if SL
using RoutedEvent = DevExpress.Xpf.Core.WPFCompatibility.SLRoutedEvent;
using RoutedEventArgs = DevExpress.Xpf.Core.WPFCompatibility.SLRoutedEventArgs;
using DevExpress.Xpf.Core.WPFCompatibility;
using DevExpress.Xpf.Core.WPFCompatibility.Helpers;
#else
using DevExpress.Xpf.Utils;
#endif
namespace UColor.WPF {
	public class UCModule : UniversalUserControl {
		#region Dependency Properties
		public static readonly RoutedEvent ModuleAppearEvent;
		public static readonly RoutedEvent BeforeModuleDisappearEvent;
		public static readonly DependencyProperty IsPopupContentInvisibleProperty;
		public static readonly DependencyProperty OwnerProperty;
		public static readonly DependencyProperty ThemeProperty;
		static UCModule() {
			Type ownerType = typeof(UCModule);
			IsPopupContentInvisibleProperty = DependencyProperty.Register("IsPopupContentInvisible", typeof(bool), ownerType, new PropertyMetadata(false, RaiseIsPopupContentInvisibleChanged));
			ModuleAppearEvent = EventManager.RegisterRoutedEvent("ModuleAppear", RoutingStrategy.Direct, typeof(RoutedEventHandler), ownerType);
			BeforeModuleDisappearEvent = EventManager.RegisterRoutedEvent("BeforeModuleDisappear", RoutingStrategy.Direct, typeof(RoutedEventHandler), ownerType);
			OwnerProperty = DependencyProperty.Register("Owner", typeof(object), ownerType, new PropertyMetadata(null));
			ThemeProperty = DependencyProperty.Register("Theme", typeof(Theme), ownerType, new PropertyMetadata(null, RaiseThemeChanged));
		}
		static void RaiseIsPopupContentInvisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
			((UCModule)d).RaiseIsPopupContentInvisibleChanged(e);
		}
		static void RaiseThemeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
			((UCModule)d).RaiseThemeChanged(e);
		}
		#endregion
		public UCModule() {
			themeSelectorHelper = new ThemeSelectorHelper();
			themeSelectorHelper.ApplicationThemeChanged += new ThePropertyChangedEventHandler<Theme>(OnApplicationThemeChanged);
		}
		void OnApplicationThemeChanged(object sender, ThePropertyChangedEventArgs<Theme> e) {
			Theme = (Theme)e.NewValue;
		}
        public UColor.WPF.Internal.BaseControlModulesPage ParentModulePage
        {
            get;
            set;
        }
		public DemoModuleControl DemoModuleControl { get { return (DemoModuleControl)Content; } }
		public object Owner { get { return GetValue(OwnerProperty); } set { SetValue(OwnerProperty, value); } }
		public Theme Theme { get { return (Theme)GetValue(ThemeProperty); } set { SetValue(ThemeProperty, value); } }
		public bool IsPopupContentInvisible { get { return (bool)GetValue(IsPopupContentInvisibleProperty); } internal set { SetValue(IsPopupContentInvisibleProperty, value); } }
		public event RoutedEventHandler ModuleAppear { add { this.AddHandler(ModuleAppearEvent, value); } remove { this.RemoveHandler(ModuleAppearEvent, value); } }
		public event RoutedEventHandler BeforeModuleDisappear { add { this.AddHandler(BeforeModuleDisappearEvent, value); } remove { this.RemoveHandler(BeforeModuleDisappearEvent, value); } }
		public virtual int GetDescriptionRowsCount() { return 1; }
		public virtual bool SupportPopupContent() { return false; }
		public virtual object GetPopupContent() { return null; }
		public virtual void UpdatePopupContent(object popupContent) { }
		public virtual bool SupportSidebarContent() { return false; }
		public virtual string GetSidebarTag() { return "Sidebar"; }
		public virtual ImageSource GetSidebarIcon() { return null; }
		public virtual ImageSource GetSidebarIconSelected() { return null; }
		public virtual object GetSidebarContent() { return null; }
		public virtual void UpdateSidebarContent(object sidebarContent) { }
		public virtual bool AllowSwitchingTheme { get { return true; } }
		public virtual bool AllowRtl { get { return true; } }
		protected internal virtual bool CanLeave() { return true; }
		ThemeSelectorHelper themeSelectorHelper;
		public bool BeginDisappear() {
			if(!CanLeave()) return false;
			RaiseBeforeModuleDisappear();
			return true;
		}
		public void EndDisappear() {
			RaiseAfterModuleDisappear();
			Clear();
		}
		public void BeginAppear() {
			RaiseBeforeModuleAppear();
		}
		public void EndAppear() {
			RaiseModuleAppear();
		}
		protected virtual void RaiseIsPopupContentInvisibleChanged(DependencyPropertyChangedEventArgs e) { }
		protected virtual void RaiseBeforeModuleAppear() { }
		protected virtual void RaiseModuleAppear() {
			this.RaiseEvent(new RoutedEventArgs() { RoutedEvent = UCModule.ModuleAppearEvent });
		}
		protected virtual void RaiseBeforeModuleDisappear() {
			this.RaiseEvent(new RoutedEventArgs() { RoutedEvent = UCModule.BeforeModuleDisappearEvent });
			DemoModuleControl.RaiseBeforeModuleDisappear();
		}
		protected virtual void RaiseAfterModuleDisappear() { }
		protected internal virtual object GetModuleDataContext() { return this; }
		protected virtual void Clear() {
#if SL
			if(DemoModuleControl != null) {
				ThemeHelper.ClearTheme(DemoModuleControl.OptionsContent);
				ThemeHelper.ClearTheme(DemoModuleControl.OptionsContentContainer);
				ThemeHelper.ClearTheme(DemoModuleControl.CodeOwner);
			}
#endif
		}
		protected virtual void RaiseThemeChanged(DependencyPropertyChangedEventArgs e) {
			if(e.NewValue == null) return;
			themeSelectorHelper.ApplicationTheme = (Theme)e.NewValue;
		}
#if !SL
		protected override Size MeasureOverride(Size constraint) {
			constraint = base.MeasureOverride(constraint);
			ClearAutomationEventsHelper.ClearAutomationEvents();
			return constraint;
		}
#endif
	}
	public enum DemoModuleControlView { Demo, CSCode, VBCode, Xaml }
	public enum DemoModuleControlOptionsView { Options, Themes, Description, Sidebar }
	[DefaultProperty("Content"), ContentProperty("Content")]
	[TemplatePart(Name = "OptionsContentContainer", Type = typeof(FrameworkElement))]
	[TemplatePart(Name = "SidebarContentContainer", Type = typeof(ContentControl))]
	[TemplatePart(Name = "ContentContainer", Type = typeof(FrameworkElement))]
	[TemplatePart(Name = "DemoContentElement", Type = typeof(FrameworkElement))]
	[TemplatePart(Name = "CornerPopup", Type = typeof(CornerPopup))]
	[TemplatePart(Name = "XamlTextViewer", Type = typeof(CodeViewControl))]
	[TemplatePart(Name = "CSCodeTextViewer", Type = typeof(CodeViewControl))]
	[TemplatePart(Name = "VBCodeTextViewer", Type = typeof(CodeViewControl))]
	[TemplatePart(Name = "CodeOwner", Type = typeof(FrameworkElement))]
	[TemplatePart(Name = "OptionsTopText", Type = typeof(FrameworkElement))]
	public class DemoModuleControl : UniversalControl {
		public static DependencyObject FindDemoContent(Type tp, DependencyObject root) {
			VisualTreeEnumerator en = new VisualTreeEnumerator(root);
			while(en.MoveNext()) {
				if(en.Current.GetType() == tp) {
					return en.Current;
				}
			}
			return null;
		}
		public static DemoModuleControl FindParentDemoModuleControl(DependencyObject d) {
			for(DependencyObject parent = d; parent != null; parent = VisualTreeHelper.GetParent(parent)) {
				if(parent is DemoModuleControl) return (DemoModuleControl)parent;
			}
			return null;
		}
		#region Dependency Properties
		public static readonly DependencyProperty OptionsTopTextProperty;
		public static readonly DependencyProperty OptionsContentProperty;
		public static readonly DependencyProperty DemoContentProperty;
		public static readonly DependencyProperty ContentProperty;
		public static readonly RoutedEvent BeforeModuleDisappearEvent;
		public static readonly DependencyProperty OptionsContentVerticalScrollVisibilityProperty;
		public static readonly DependencyProperty ViewProperty;
		public static readonly DependencyProperty OptionsViewProperty;
		public static readonly DependencyProperty OptionsExpandedProperty;
		public static readonly DependencyProperty SupressGroupFramePaddingInOptionsProperty;
		static DemoModuleControl() {
			Type ownerType = typeof(DemoModuleControl);
			OptionsTopTextProperty = DependencyProperty.Register("OptionsTopText", typeof(string), ownerType, new PropertyMetadata(null));
			ContentProperty = RegisterContentProperty("Content", typeof(FrameworkElement), ownerType, null, null);
			DemoContentProperty = DependencyProperty.Register("DemoContent", typeof(DependencyObject), ownerType, new PropertyMetadata(null));
			OptionsContentProperty = RegisterContentProperty("OptionsContent", typeof(FrameworkElement), ownerType, null, null);
			BeforeModuleDisappearEvent = EventManager.RegisterRoutedEvent("BeforeModuleDisappear", RoutingStrategy.Direct, typeof(RoutedEventHandler), ownerType);
			OptionsContentVerticalScrollVisibilityProperty = DependencyProperty.Register("OptionsContentVerticalScrollVisibility", typeof(ScrollBarVisibility), ownerType, new PropertyMetadata(ScrollBarVisibility.Auto, RaiseOptionsContentVerticalScrollVisibilityChanged));
			ViewProperty = DependencyProperty.Register("View", typeof(DemoModuleControlView), ownerType, new PropertyMetadata(DemoModuleControlView.Demo, RaiseViewChanged));
			OptionsViewProperty = DependencyProperty.Register("OptionsView", typeof(DemoModuleControlOptionsView), ownerType, new PropertyMetadata(DemoModuleControlOptionsView.Options, RaiseOptionsViewChanged));
			OptionsExpandedProperty = DependencyProperty.Register("OptionsExpanded", typeof(bool), ownerType, new PropertyMetadata(true, RaiseOptionsExpandedChanged));
			SupressGroupFramePaddingInOptionsProperty = DependencyProperty.Register("SupressGroupFramePaddingInOptions", typeof(bool), ownerType, new PropertyMetadata(true, RaiseSupressGroupFramePaddingInOptionsChanged));
		}
		ScrollBarVisibility optionsContentVerticalScrollVisibilityValue = ScrollBarVisibility.Auto;
		DemoModuleControlView viewValue = DemoModuleControlView.Demo;
		DemoModuleControlOptionsView optionsViewValue = DemoModuleControlOptionsView.Options;
		bool optionsExpandedValue = true;
		bool supressGroupFramePaddingInOptionsValue = true;
		static void RaiseOptionsContentVerticalScrollVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
			((DemoModuleControl)d).optionsContentVerticalScrollVisibilityValue = (ScrollBarVisibility)e.NewValue;
		}
		static void RaiseViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
			((DemoModuleControl)d).viewValue = (DemoModuleControlView)e.NewValue;
		}
		static void RaiseOptionsViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
			((DemoModuleControl)d).optionsViewValue = (DemoModuleControlOptionsView)e.NewValue;
		}
		static void RaiseOptionsExpandedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
			((DemoModuleControl)d).optionsExpandedValue = (bool)e.NewValue;
		}
		static void RaiseSupressGroupFramePaddingInOptionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
			((DemoModuleControl)d).supressGroupFramePaddingInOptionsValue = (bool)e.NewValue;
		}
		#endregion
		public DemoModuleControl() {
			this.SetDefaultStyleKey(typeof(DemoModuleControl));
			FocusHelper.SetFocusable(this, false);
		}
		public bool OptionsExpanded { get { return optionsExpandedValue; } set { SetValue(OptionsExpandedProperty, value); } }
		public ScrollBarVisibility OptionsContentVerticalScrollVisibility { get { return optionsContentVerticalScrollVisibilityValue; } set { SetValue(OptionsContentVerticalScrollVisibilityProperty, value); } }
		public DemoModuleControlView View { get { return viewValue; } set { SetValue(ViewProperty, value); } }
		public DemoModuleControlOptionsView OptionsView { get { return optionsViewValue; } set { SetValue(OptionsViewProperty, value); } }
		public string OptionsTopText { get { return (string)GetValue(OptionsTopTextProperty); } set { SetValue(OptionsTopTextProperty, value); } }
		public FrameworkElement Content { get { return (FrameworkElement)GetValue(ContentProperty); } set { SetValue(ContentProperty, value); } }
		public DependencyObject DemoContent { get { return (DependencyObject)GetValue(DemoContentProperty); } set { SetValue(DemoContentProperty, value); } }
		public FrameworkElement OptionsContent { get { return (FrameworkElement)GetValue(OptionsContentProperty); } set { SetValue(OptionsContentProperty, value); } }
		public UCModule DemoModule { get { return (UCModule)Parent; } }
		public FrameworkElement ContentContainer { get; private set; }
		public FrameworkElement OptionsContentContainer { get; private set; }
		public ContentControl SidebarContentContainer { get; private set; }
		public FrameworkElement DemoContentElement { get; private set; }
		public FrameworkElement DescriptionContentContainer { get; private set; }
		public CornerPopup CornerPopup { get; private set; }
		public CodeViewControl XamlTextViewer { get; private set; }
		public CodeViewControl CSCodeTextViewer { get; private set; }
		public CodeViewControl VBCodeTextViewer { get; private set; }
		public FrameworkElement CodeOwner { get; private set; }
		public event RoutedEventHandler BeforeModuleDisappear { add { this.AddHandler(BeforeModuleDisappearEvent, value); } remove { this.RemoveHandler(BeforeModuleDisappearEvent, value); } }
		public bool SupressGroupFramePaddingInOptions { get { return supressGroupFramePaddingInOptionsValue; } set { SetValue(SupressGroupFramePaddingInOptionsProperty, value); } }
		protected internal virtual void RaiseBeforeModuleDisappear() {
			this.RaiseEvent(new RoutedEventArgs() { RoutedEvent = DemoModuleControl.BeforeModuleDisappearEvent });
		}
		void UpdateOptionsContentDataContext(object dataContext) {
			if(OptionsContent != null) {
				if(dataContext == null)
					OptionsContent.SetBinding(FrameworkElement.DataContextProperty, new Binding("DataContext") { Source = this, Mode = BindingMode.OneWay });
				else
					OptionsContent.DataContext = dataContext;
			}
		}
		protected override void OnLoaded(object sender, System.Windows.RoutedEventArgs e) {
			base.OnLoaded(sender, e);
			if(DemoModule.SupportPopupContent()) {
				if(CornerPopup.PopupContent == null) CornerPopup.PopupContent = DemoModule.GetPopupContent();
				else DemoModule.UpdatePopupContent(CornerPopup.PopupContent);
			} else {
				if(CornerPopup != null)
					CornerPopup.PopupContent = null;
			}
			if(DemoModule.SupportSidebarContent()) {
				if(SidebarContentContainer.Content == null) SidebarContentContainer.Content = DemoModule.GetSidebarContent();
				else DemoModule.UpdateSidebarContent(DemoModule.GetSidebarContent());
			} else {
				if(SidebarContentContainer != null)
					SidebarContentContainer.Content = null;
			}
		}
		protected override void OnApplyTemplateOverride() {
			base.OnApplyTemplateOverride();
			UpdateOptionsContentDataContext(DemoModule.GetModuleDataContext());
			ContentContainer = (FrameworkElement)GetTemplateChild("ContentContainer");
			DemoContentElement = (FrameworkElement)GetTemplateChild("DemoContentElement");
			OptionsContentContainer = (FrameworkElement)GetTemplateChild("OptionsContentContainer");
			SidebarContentContainer = (ContentControl)GetTemplateChild("SidebarContentContainer");
			CornerPopup = (CornerPopup)GetTemplateChild("CornerPopup");
			XamlTextViewer = (CodeViewControl)GetTemplateChild("XamlTextViewer");
			CSCodeTextViewer = (CodeViewControl)GetTemplateChild("CSCodeTextViewer");
			VBCodeTextViewer = (CodeViewControl)GetTemplateChild("VBCodeTextViewer");
			DescriptionContentContainer = (FrameworkElement)GetTemplateChild("DescriptionContentContainer");
			CodeOwner = (FrameworkElement)GetTemplateChild("CodeOwner");
		}
#if !SL
		protected override Size MeasureOverride(Size constraint) {
			constraint = base.MeasureOverride(constraint);
			ClearAutomationEventsHelper.ClearAutomationEvents();
			return constraint;
		}
#endif
	}
}
